/*
 * dns_proc.cpp
 *
 *  Created on: Dec 11, 2013
 *      Author: m
 */

/*
* dns_proc.cpp: implementation of the remote procedures
*/

#include <stdio.h>
#include <rpc/rpc.h> /* always needed */
#include "AgentAddressCommon.h"
#include "agent_address_service.h"
#include "../../common/ArchivoIni.h"
#include "../../common/StringUtils.h"
#include "../../IPC/Sequence.h"

int * getaddress_1_svc(void *, struct svc_req *)
{
	static int result; /* must be static! */

	ipc::Sequence numerador = ipc::Sequence::get(AGENT_ADDRESS_SEQ_PATH,AGENT_ADDRESS_SEQ_KEY);

	result = numerador.getNext();

	return &result;
}


int * unregister_address_name_1_svc(char **name, struct svc_req *req)
{
    static int result; /* must be static! */

    std::string touchCmd = "touch ";
    touchCmd += AGENT_ADDRESS_FILE;
    system( touchCmd.c_str() );

    MapaIni dnsTable = ArchivoIni::parsearComoIni( AGENT_ADDRESS_FILE );

    result = dnsTable.erase( *name );

    ArchivoIni::guardarComoIni( AGENT_ADDRESS_FILE, dnsTable );

    return &result;
}

int * resolve_address_name_1_svc(char **name, struct svc_req *req)
{
    static int result; /* must be static! */

    std::string touchCmd = "touch ";
    touchCmd += AGENT_ADDRESS_FILE;
    system( touchCmd.c_str() );

    MapaIni agentNameTable = ArchivoIni::parsearComoIni( AGENT_ADDRESS_FILE );

    std::string address;

    address = agentNameTable[*name];

    if(address=="")
    	result = -1;
    else
    	result = StringUtils::StringToNumber<int>(address);

    return &result;
}

int * register_address_name_static_1_svc(dns_record_agent_address *record, struct svc_req *req)
{
    static int result; /* must be static! */

    std::string touchCmd = "touch ";
    touchCmd += AGENT_ADDRESS_FILE;
    system( touchCmd.c_str() );

    MapaIni agentAddressTable = ArchivoIni::parsearComoIni( AGENT_ADDRESS_FILE );

    std::string agentAddress = record->address;

    std::cout << "Statically register Agent:"<<record->name<< " address:"<< agentAddress<<std::endl;

    if(agentAddressTable[record->name] == "")
    {
		if(agentAddress == "0")
		{
			std::cout << "Pidiendo address"<<std::endl;
			ipc::Sequence numerador = ipc::Sequence::get(AGENT_ADDRESS_SEQ_PATH,AGENT_ADDRESS_SEQ_KEY);
			agentAddress = StringUtils::NumberToString(numerador.getNext());
		}
    }
    else
    	agentAddress = agentAddressTable[record->name];

    agentAddressTable[record->name] = agentAddress;

    ArchivoIni::guardarComoIni( AGENT_ADDRESS_FILE, agentAddressTable );

    result = StringUtils::StringToNumber<int>(agentAddress);

    return &result;
}

int * register_address_name_dynamic_1_svc(dns_record_agent_address *record, struct svc_req *req)
{
    static int result; /* must be static! */

    std::string agentName(record->name);
    std::string touchCmd = "touch ";
    touchCmd += AGENT_ADDRESS_FILE;
    system( touchCmd.c_str() );

    MapaIni agentAddressTable = ArchivoIni::parsearComoIni( AGENT_ADDRESS_FILE );

    std::string agentAddress = record->address;

    if(agentAddress != "0")
    	agentName +=agentAddress;

	std::cout << "Dynamically register Agent:"<<agentName<< " address:"<< agentAddress<<std::endl;

	//If the agent is not present
    if(agentAddressTable.find(agentName) == agentAddressTable.end())
    {
		std::cout << "Pidiendo address"<<std::endl;
		ipc::Sequence numerador = ipc::Sequence::get(AGENT_ADDRESS_SEQ_PATH,AGENT_ADDRESS_SEQ_KEY);
		agentAddress = StringUtils::NumberToString(numerador.getNext());
		agentName = std::string(record->name)+agentAddress;
    }
    else
    	agentAddress = agentAddressTable[agentName];

    agentAddressTable[agentName] = agentAddress;

    ArchivoIni::guardarComoIni( AGENT_ADDRESS_FILE, agentAddressTable );

    result = StringUtils::StringToNumber<int>(agentAddress);

    return &result;
}

char ** getagentbyid_1_svc(int *agentId, struct svc_req *req)
{
	static char *result=new char[1000];

	std::cout << "Buscando agent name por id:"<< *agentId<<std::endl;

	strcpy(result,"");

	MapaIni agentNameTable = ArchivoIni::parsearComoIni( AGENT_ADDRESS_FILE );

	bool found = false;
	MapaIni::iterator it = agentNameTable.begin(); // internalMap is std::map

	while(it != agentNameTable.end())
	{
		found = (it->second == StringUtils::NumberToString(*agentId));

		if(found)
		{
			strcpy(result,it->first.c_str());
			break;
		}

		++it;
	}

	if(found)
		std::cout << "Se encontro el name:"<< *result<<std::endl;
	else
		std::cout << "Id no encontrado"<<std::endl;

	return &result;
}

